import StorageTools from '../tools/StorageTools'
import { Message } from 'element-ui'
import {refreshToken,handleAxiosRequestConfig,isAccessTokenNearExpires,isAccessTokenExpires,isRefreshTokenExpires} from '../components/login/HandleToken'

// 是否正在刷新的标记
let isRefreshing = false
// 重试队列，每一项将是一个待执行的函数形式
const requests = []

export default function axiosConfig(axios,vue){
    // 全部使用api前缀
    let baseUrl = process.env.NODE_ENV === 'development' ? '/api' : '/api'

    vue.prototype.$baseURL = {
        base: baseUrl + '/grape-base',
        auth: baseUrl + '/grape-auth',
        file: baseUrl + '/grape-file',
        attend: baseUrl + '/grape-attend',
        workflow: baseUrl + '/grape-workflow',
        wx: baseUrl + '/grape-wx',
        composite: baseUrl + '/grape-composite',
        sequence: baseUrl + '/grape-sequence',
        crm: baseUrl + '/grape-crm',
        house: baseUrl + '/grape-house',
    }
    // 兼容一下后台单机运行，下面两种判断，同时支持了环境变量和运行时动态设置
    if(window.portalOneBackend || process.env.VUE_APP_PORTALONEBACKEND == 'true'){
        for(let key in vue.prototype.$baseURL){
            vue.prototype.$baseURL[key] = baseUrl
        }
    }

    // 请求拦截器
    axios.interceptors.request.use(
        config => {
            // 如果token已过期或快要过期且刷新token没有过期，尝试刷新token
            if((isAccessTokenNearExpires() || isAccessTokenExpires()) && isRefreshTokenExpires() === false){
                if (!isRefreshing) {
                    isRefreshing = true
                    return refreshToken(axios,vue).then(res => {
                        // 已经刷新了token，将所有队列中的请求进行重试
                        handleAxiosRequestConfig(config)
                        requests.forEach(cb => cb())
                        return (config)
                    }).catch(res => {
                        console.error(res)
                        Message.error('刷新token失败，具体信息请查看控制台日志')
                    }).finally(() => {
                        isRefreshing = false
                    })
                } else {
                    // 刷新token本身不拦截
                    if(config.url.indexOf('grant_type=refresh_token')> 0){
                        return config
                    }
                    // 正在刷新token，将返回一个未执行resolve的promise
                    return new Promise((resolve) => {
                        // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
                        requests.push(() => {
                            resolve(config)
                        })
                    })
                }
            }

            handleAxiosRequestConfig(config)
            return config
        },
        err => {
            return Promise.reject(err)
        })
    // 添加响应拦截器
    axios.interceptors.response.use(function (response) {
        // 对响应数据做点什么
        return response
    }, function (error) {
        // 对响应错误做点什么
        if (!error.response) {
            //Message.error('网络异常请检查服务请求是否正常，或这是一个bug，请联系管理员')
            // todo 记录异常信息到后台方便定位问题
            //return
        }else {
            // 如果未登录设置当前访问url，登录成功后跳转回来
            if(error.response.status == 401 && window.location.href.indexOf('/login') == -1){
                StorageTools.sessionSet('beforeLoginUrl',window.location.href)
            }
            if(error.response.data){
                let responseData = error.response.data
                if(typeof responseData == 'string'){
                    // 开发的时候代理不到后台，说明后台服务不可用
                    if(responseData.indexOf('Proxy error:') >=0){
                        Message.error('网络错误或服务不可用，请联系管理员')
                    }
                }

            }
        }
        return Promise.reject(error)
    })

}
